/*
** mxs.h for libmxs in /home/rannou_s/work/c/tools/includes
** 
** Made by sebastien rannou
** Login   <rannou_s@epitech.net>
** 
** Started on  Sun Sep  6 18:47:16 2009 sebastien rannou
** Last update Sun Sep  6 20:47:32 2009 sebastien rannou
*/

#ifndef	LIBMXS_H
#define	LIBMXS_H

/**!
 * If lists are disabled, ini can't work
 */

# define	ERROR		-1
# define	SUCCESS		0

/**!
 * -- LISTS
 * This section can't be disabled as it's the heart of other modules that
 * would leave the library empty...
 * This implementation use double-linked list (prev and next elements)
 * Each time a new list is created, there's also a listi_s structure allocated
 * which will contains additionnal informations (current len of the list?) so
 * as to win some CPU time on some operations.
 */

# ifndef	DISABLE_LIST

typedef struct		listi_s		/* list informations */
{
  int			nb_elements;	/* number of elements in list */
}			listi_t;

typedef struct		list_s
{
  struct list_s		*li_prev;	/* previous element in list */
  struct list_s		*li_next;	/* next element in list */
  struct listi_s	*li_info;	/* informations about the list */
  void			*data;		/* allocated pointer */
}			list_t;

#define	list_len(elem)	(elem->li_info->nb_elements)

int		/* Let's remove a list */
list_free(list_t **li_start, void (*f)(void *));

int		/* Let's remove an element from a list */
list_pop(list_t **li_start, list_t *li_element);

list_t *	/* Let's fetch an entry from a data */
list_fetch(list_t *start, void *data);

int		/* Let's remove an element according to its data */
list_pop_data(list_t **li_start, void *data);

int		/* Let's push a new element to a list */
list_push(list_t **li_start, void *data);

#endif /* DISABLE_LIST */

/**!
 * -- ERRORS
 * This section contains stuff related to errors.
 * The library works well without this stuff, but enable it is a good way
 * to have a diagnostic on what's going wrong.
 */

# ifndef	DISABLE_ERRORS

#  define	ERR_LOG_FILE	"error.log"
#  define	ERR_FMT_LOG	"error raised in [%s] on line %d: "

/**!
 * These flags are used to control the behavior of errors.
 * Each flags is a feature which is executed when an error is raised.
 */

#  define	ERR_T_DISPLAY	0x01 /* 0000 0001 -> print error's message */
#  define	ERR_T_LOG	0x02 /* 0000 0010 -> log error's message */
#  define	ERR_T_DIE	0x04 /* 0000 0100 -> exit the program */
#  define	ERR_T_ERRNO	0x08 /* 0000 1000 -> add errno message */

void	error_handler(int line, char *file, int code, ...);

/**!
 * Maccro to make easier tracing of errors in development mode
 */

#  define ERR_RAISE(...)  error_handler(__LINE__, __FILE__, __VA_ARGS__)

/**!
 * Default errors (already pre-defined)
 */

#  define	EC_NULL_PTR	0x01
#  define	EC_NULL_PTR_DIE	0x02

#  define	EC_SYS_MALLOC	0x11

# endif	/* DISABLE_ERRORS */

/**!
 * -- INI
 * This section contains stuff related to parsing of ini files
 */

# ifndef	DISABLE_INI

typedef struct		ini_section_s	/* content of a section */
{
  char			*name;		/* section's name */
  list_t		*content_li;	/* list of content (ini_content_t *) */
  int			content_num;	/* number of contents */
}			ini_section_t;

typedef struct		ini_content_s	/* content of a parameter */
{
  char			*name;		/* parameter's name */
  char			*value;		/* parameter's value */
  ini_section_t		*section_is;	/* hash on section's content */
}			ini_content_t;

typedef struct		ini_s		/* content of a .ini file */
{
  char			*name;		/* file's name */
  list_t		*sections_is;	/* list of sections */
  list_t		*content_ic;	/* list of contents */
  int			section_num;	/* number of sections */
  int			content_num;	/* number of contents */
}			ini_t;

ini_section_t *	/* returns a section from its name */
ini_retrieve_section(ini_t *ini, char *name);

ini_t *		/* primary function, parses an ini file */
ini_parse_file(char *name);

char *		/* returns an entry related by its section and its key */
ini_retrieve_entry(ini_t *ini, char *section, char *key);

char *		/* returns an entry from its section */
ini_retrieve_entry_from_section(ini_section_t *section, char *key);

int		/* returns 1 if ON, 0 if OFF, -1 on error */
ini_retrieve_entry_from_section_bool(ini_section_t *section, char *key);

void		/* free everything that's was loaded from a file */
ini_free_main(void *ini);

# endif	/* DISABLE_INI */

/**!
 * -- LOG
 * Quite a simple module, can be used to have a good diagnostic
 * in so far as it provides informations about the location of the
 * call.
 */

# ifndef	DISABLE_LOG

#  define	LOG_PREFIX_OK	"+ "

int	/* Simply prints a message */
log_print(int line, char *file, char *prefix, char *fmt, ...);

#  define	LOG(...)log_print(__LINE__, __FILE__,		\
				  LOG_PREFIX_OK, __VA_ARGS__)

# endif	/* DISABLE_LOG */

/**!
 * -- SHA1
 * Provides some functions to generate hashes from different kind of outputs
 */

# ifndef	DISABLE_SHA1

char *	/* Returns an allocated hash of the file */
sha1_file(char *path);

char *	/* Returns an allocated string representing the hashed input */
sha1_string(char *input);

# endif /* DISABLE_SHA1 */

#endif	/* LIBMXS_H */
